package my.georings.dialog;

import java.util.ArrayList;
import java.util.List;

import my.Utils;
import my.georings.GeoPhoneRingsApp;
import my.georings.R;
import my.georings.data.MyLocation;
import my.georings.data.MyLocationCurrent;
import my.georings.map.ChooseLocationItomizedOverlay;
import my.georings.service.LocationChangeService;
import my.georings.service.MyLocationChangedListener;
import android.app.AlertDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;



public class ChooseLocationMapDialog extends MapActivity implements OnClickListener, MyLocationChangedListener{

	private ChooseLocationItomizedOverlay overlays;
	private MapView mapView;
	protected MyLocationCurrent myLocation = new MyLocationCurrent();
	private LocationChangeService boundService;
	private boolean resume = true;
	
	
	public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.mapget);
        
        Drawable drawable = this.getResources().getDrawable(R.drawable.pin);
        overlays = new ChooseLocationItomizedOverlay(drawable, this);
        
        mapView = (MapView) findViewById(R.id.mapget_MapView);
        initMapView();
        ((Button)findViewById(R.id.mapget_Ok)).setOnClickListener(this);
        ((Button)findViewById(R.id.mapget_cancel)).setOnClickListener(this);
        ((Button)findViewById(R.id.mapget_current)).setOnClickListener(this);
    }
	
	@Override
	protected void onResume(){
		super.onResume();
		
		boolean hasLocation = false;
		
		if(((GeoPhoneRingsApp)getApplication()).checkServiceRunning()){
        	doBindService();
        }else{
        	LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
        	Location lastLocation = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
    		if(lastLocation == null)
    			lastLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
    		
    		if(lastLocation == null){
    			Toast toast = Toast.makeText(this, "The application could not get your last location. Please turn on the service on settings tab.", Toast.LENGTH_SHORT);
    			toast.show();
    		}else{
    			Toast toast = Toast.makeText(this, "Your location may not be accurate. Please turn on the service on settings tab.", Toast.LENGTH_SHORT);
    			toast.show();
    			myLocation.setPoint(Utils.geoPointFromLocation(lastLocation));
    			hasLocation = true;
    		}
        }
		
		refreshLocationOverlays();
		if(hasLocation)
			refreshCurrentLocationView();
	}
	
	
	@Override
	protected void onPause(){
		doUnbindService();
		super.onPause();
	}
	
	
	@Override
	protected boolean isRouteDisplayed(){
		return false;
	}
	
	private void initMapView(){
        mapView.setBuiltInZoomControls(true);
        mapView.getController().setZoom(15);
	}
	
	protected void refreshCurrentLocationView(){
		overlays.addLocationItem(myLocation);
		mapView.invalidate();
		if(resume){
			mapView.getController().animateTo(myLocation.getPoint());
			resume = false;
		}
	}
	
	private void refreshLocationOverlays(){
		overlays.clear();
		ArrayList<MyLocation> list =  ((GeoPhoneRingsApp)getApplication()).getMyLocationsManager().getList();
		
		for(int i = 0; i < list.size(); ++i){
			overlays.addLocationItem((MyLocation)list.get(i));
		}
		List<Overlay> mapOverlays = mapView.getOverlays();
        mapOverlays.add(overlays);
	}

	
	@Override
	public void onClick(View v) {
		Intent thisIntent = getIntent();
		
		if(v.getId() == R.id.mapget_Ok){
			GeoPoint p = overlays.getNewLocationPoint();
			thisIntent.putExtra("lat", p.getLatitudeE6());
			thisIntent.putExtra("long", p.getLongitudeE6());
			setResult(RESULT_OK, thisIntent);
			finish();
		}else if(v.getId() == R.id.mapget_cancel){
			setResult(RESULT_CANCELED, thisIntent);
			finish();
		}else if(v.getId() == R.id.mapget_current){
			overlays.setNewLocationPoint(myLocation.getPoint());
			new Handler().post(new Runnable() {
				
				@Override
				public void run() {
					mapView.getController().animateTo(myLocation.getPoint());
				}
			});
		}
	}
	
	@Override
	public void onMyLocationChanged(Location newLocation) {
		myLocation.setPoint(Utils.geoPointFromLocation(newLocation));
		myLocation.setAccuracy(newLocation.getAccuracy());
		refreshCurrentLocationView();
	}

	private void doBindService() {
		Intent myIntent = new Intent(this, my.georings.service.LocationChangeService.class);
		this.bindService(myIntent, boundConnection, Context.BIND_AUTO_CREATE);
	}

	private void doUnbindService() {
	    if (boundService != null) {
	    	boundService.removeListener(this);
	    	this.unbindService(boundConnection);
	        boundService = null;
	    }
	}

	private ServiceConnection boundConnection = new ServiceConnection() {
	    public void onServiceConnected(ComponentName className, IBinder service) {
	    	boundService = ((LocationChangeService.LocationChangeBinder)service).getService();
	    	
	    	Location newLocation = boundService.getLastLocation();
	    	if(newLocation == null){
	    		Toast toast = Toast.makeText(ChooseLocationMapDialog.this, "The application could not get your last location.", Toast.LENGTH_SHORT);
    			toast.show();
	    	}else{
		    	onMyLocationChanged(newLocation);
	    	}
	    	
	    	boundService.addListener(ChooseLocationMapDialog.this);
	    }

	    public void onServiceDisconnected(ComponentName className) {
	    	boundService = null;
	    }
	};
	
	@Override
	public void onNoProviderAvailable() {
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
    	builder.setMessage("Please turn on gps or wifi localization in your phone settings and restart application.")
    	       .setCancelable(false)
    	       .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
    	           public void onClick(DialogInterface dialog, int id) {
    	                ChooseLocationMapDialog.this.finish();
    	           }
    	       });
    	AlertDialog alert = builder.create();
    	alert.show();
	}
}
